package dk.itu.spvc.tourtracker.gui;

import java.util.List;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;
import com.skyhookwireless.wps.IPLocation;
import com.skyhookwireless.wps.IPLocationCallback;
import com.skyhookwireless.wps.Location;
import com.skyhookwireless.wps.WPSContinuation;
import com.skyhookwireless.wps.WPSLocation;
import com.skyhookwireless.wps.WPSLocationCallback;
import com.skyhookwireless.wps.WPSPeriodicLocationCallback;
import com.skyhookwireless.wps.WPSReturnCode;

import dk.itu.spvc.tourtracker.model.Wps;

/**
 * A map activity that uses WPS (SkyHook) to get current location
 * Not finished - branched
 * @author Alvis
 */
public class WpsMap extends MapActivity {

	// PRIVATE FIELDS ---------------------------------------------------------
	
	// Debug
	private static final String TAG = "TourTracker";
	private static final boolean D = true;
	
	private MapView mapView;
	private MapController mapController;
	private Wps wps;
	
	
	// OVERRIDES --------------------------------------------------------------
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);        

     	// Create the WPS instance, passing in our Context
        wps = new Wps(this);
        _stop = false;        
        
        // Initialize the Handler which will display location data in the map view. 
        // We use a Handler because UI updates must occur in the UI thread
        setUIHandler();
        
        // TODO get location
        wps.getWPSLocation(_callback);
        
        // Init map view
        mapView = (MapView) findViewById(R.id.mapview);        
        mapView.setBuiltInZoomControls(true);  
        mapView.setSatellite(false);
        mapView.setStreetView(false);
        mapView.setClickable(true);
        mapView.setEnabled(true);
        
        // Init map controller
        mapController = mapView.getController();
        mapController.setZoom(15);
 
    }
	
	@Override
    protected boolean isRouteDisplayed() {
        return false;
    }
	
	
	// PRIVATE METHODS --------------------------------------------------------
	
	/**
     * Update the map view with location
     * @param location
     */
    private void updateLocation (Location location) {    	
    	
        List<Overlay> mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.androidmarker);
        PinOverlay itemizedOverlay = new PinOverlay(getBaseContext(), drawable);
        
        int lat = (int)(location.getLatitude() * 1E6);
        int lng = (int)(location.getLongitude() * 1E6);
        
        GeoPoint point = new GeoPoint(lat, lng);
        OverlayItem overlayItem = new OverlayItem(point, "Current Location", "Hello, Current Location!");
        
        //itemizedOverlay.addOverlay(overlayItem);
        mapOverlays.add(itemizedOverlay);
        
    }
    
    
	// CALLBACK ---------------------------------------------------------------
	
	private final LocationCallback _callback = new LocationCallback();
	private boolean _stop;
	
	/**
     * A single callback class that will be used to handle all notifications sent by WPS to our app.
     */
    private class LocationCallback
        implements IPLocationCallback,
                   WPSLocationCallback,
                   WPSPeriodicLocationCallback
    {
        public void done()
        {
            // Tell the UI thread to re-enable the buttons
            _handler.sendMessage(_handler.obtainMessage(DONE_MESSAGE));
        }

        public WPSContinuation handleError(WPSReturnCode error)
        {
            // Send a message to display the error
            _handler.sendMessage(_handler.obtainMessage(ERROR_MESSAGE, error));
            // return WPS_STOP if the user pressed the Stop button
            if (! _stop)
                return WPSContinuation.WPS_CONTINUE;
            else
                return WPSContinuation.WPS_STOP;
        }

        public void handleIPLocation(IPLocation location)
        {
            // Send a message to display the location
            _handler.sendMessage(_handler.obtainMessage(LOCATION_MESSAGE, location));
        }

        public void handleWPSLocation(WPSLocation location)
        {
            // send a message to display the location
            _handler.sendMessage(_handler.obtainMessage(LOCATION_MESSAGE, location));
        }

        public WPSContinuation handleWPSPeriodicLocation(WPSLocation location)
        {
            _handler.sendMessage(_handler.obtainMessage(LOCATION_MESSAGE, location));
            // return WPS_STOP if the user pressed the Stop button
            if (! _stop)
                return WPSContinuation.WPS_CONTINUE;
            else
                return WPSContinuation.WPS_STOP;
        }
    }
    
    // HANDLER ----------------------------------------------------------------
    
    private Handler _handler;
    
    // Handler understands three messages:
    // a location, an error, or a finished request
    private static final int LOCATION_MESSAGE = 1;
    private static final int ERROR_MESSAGE = 2;
    private static final int DONE_MESSAGE = 3;

    private void setUIHandler()
    {
        _handler = new Handler()
        {
            @Override
            public void handleMessage(final Message msg)
            {
                switch (msg.what)
                {
	                case LOCATION_MESSAGE:
	                    Location location = (Location) msg.obj;
	                    if(D) Log.d(TAG, "Map - Location received - " + location.toString());
	                    updateLocation(location);
	                    return;
	                case ERROR_MESSAGE:
	                    String errorName = ((WPSReturnCode) msg.obj).name();
	                    if(D) Log.w(TAG, "Map - Error received - " + errorName);
	                    return;
	                case DONE_MESSAGE:
	                    //deactivateStopButton();
	                    _stop = false;
                }
            }
        };
    }
    	
}
